/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[Overriding.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package objectOriented;

/**
 * 方法重写<br/>
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class Overriding {

	@SuppressWarnings("static-access")
	public static void main(String[] args) {

		// 继承时属性的隐藏问题
		DerivedClass derivedClass = new DerivedClass();
		System.out.println("DerivedClass name is " + derivedClass.name + ", DerivedClass age is " + derivedClass.age
				+ " ,Kind is " + derivedClass.kind);// 此处得到都是DerivedClass类的变量值

		// 将DerivedClass类型转换为BaseClass类型, 即多态情况
		// BaseClass baseClass = derivedClass;
		BaseClass baseClass = new DerivedClass();
		System.out.println("转换为BaseClass之后的name is " + baseClass.name + ", age is " + baseClass.age + " ,kind is "
				+ baseClass.kind);
		/**
		 * 结论:<br/>
		 * 
		 * 父类的实例变量和类变量能被子类的同名变量遮盖[隐藏], 将子类对象转换为父类对象后, 可以访问父类对象的实例变量和类变量<br/>
		 * 在子类中如果需要访问父类中被隐藏的实例变量, 需要使用"super.属性名"<br/>
		 * 在子类中如果需要访问父类中被隐藏的类变量, 需要使用"父类名.属性名"<br/>
		 */
		System.out.println("子类访问父类被隐藏的实例变量: " + derivedClass.getBaseClassName());
		System.out.println("子类访问父类被隐藏的类变量: " + derivedClass.getBaseClassKind());

		// 继承时方法的覆盖与隐藏问题
		derivedClass.getName();
		derivedClass.getKind();
		baseClass.getName();
		baseClass.getKind();
		/**
		 * 结论:<br/>
		 * 
		 * 父类的静态方法被子类的同名静态方法隐藏, 而父类的实例方法被子类的实例方法覆盖[重写]<br/>
		 * 将子类转换为父类对象后[多态], 能访问父类的静态方法,不能访问父类的实例方法[调用的方法为被子类重写后的方法]<br/>
		 * 试图用子类的静态方法隐藏父类中同样标识的实例方法是不合法的, 编译器将会报错<br/>
		 * 试图用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的, 编译器会报错<br/>
		 * 静态方法和最终方法[带关键字final的方法]不能被覆盖<br/>
		 */
	}
}

/**
 * 父类
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
class BaseClass {

	// 类变量, BaseClass的类别
	public static String kind = "objectOriented.Overriding.BaseClass";
	// 类变量, BaseClass的年龄
	public static int age = 50;
	// 实例变量, BaseClass的名称
	public String name = "BaseClass";

	// 静态方法, 获得BaseClass的类别
	public static String getKind() {
		System.out.println("BaseClass getKind() method called");
		return kind;
	}

	// 静态方法, 获得BaseClass的年龄
	public static int getAge() {
		System.out.println("BaseClass getAge() method called");
		return age;
	}

	// 实例方法, 获得BaseClass的名称
	public String getName() {
		System.out.println("BaseClass getName() method called");
		return name;
	}
}

/**
 * 子类
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
class DerivedClass extends BaseClass {

	// 类变量, DerivedClass的类别
	public static String kind = "objectOriented.Overriding.DerivedClass";
	// 类变量, DerivedClass的年龄
	public static int age = 25;
	// 实例变量, DerivedClass的名称
	public String name = "DerivedClass";

	// 静态方法, 获得DerivedClass的类别
	public static String getKind() {
		System.out.println("DerivedClass getKind() method called");
		return kind;
	}

	// 静态方法, 获得DerivedClass的年龄
	public static int getAge() {
		System.out.println("DerivedClass getAge() method called");
		return age;
	}

	// 实例方法, 获得DerivedClass的名称
	@Override
	public String getName() {
		System.out.println("DerivedClass getName() method called");
		return name;
	}

	// 实例方法, 获得BaseClass的名称
	public String getBaseClassName() {
		return super.name;
	}

	// 静态方法, 获得BaseClass的类别
	public static String getBaseClassKind() {
		return BaseClass.kind;
	}
}
